package tesseract

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
	"wisdom_education_in_kunshan/ocr"
)

type tesseractConfig struct {
	Dir  string   `json:"dir"`
	Args []string `json:"args"`
}

func init() {
	cfgFile, err := os.Open("tesseract.cfg")
	if err != nil {
		return
	}
	tcfg := &tesseractConfig{}
	decoder := json.NewDecoder(cfgFile)
	err = decoder.Decode(tcfg)
	if err != nil {
		return
	}
	ocr.DefaultOCR = tcfg
}

func (t tesseractConfig) OCR(args ...string) (string, bool) {
	imagePath := args[0]
	if !processCodeImage(imagePath, imagePath) {
		log.Println("验证码图片处理失败")
		return ocr.Null, false
	}
	code, err := t.doOCR(args[0])
	if err != nil {
		log.Println("OCR err", err)
	}
	return code, len(code) > 0
}

func processCodeImage(path, savePath string) bool {
	err := Translate(path, savePath)
	if err != nil {
		log.Println("Translate Code Image err", err)
		return false
	}
	return true
}

func isFile(path string) (bool, error) {
	f, err := os.Stat(path)
	if err != nil {
		return false, err
	}
	return !f.IsDir(), nil
}
func (t *tesseractConfig) doOCR(imagePath string) (string, error) {
	c, err := isFile(imagePath)
	if !c {
		return ocr.Null, err
	}
	tesseractPath, err := getTesseractPath(t.Dir)
	if err != nil {
		return ocr.Null, err
	}
	nt := time.Now()
	sep := string(os.PathSeparator)
	arg := make([]string, len(t.Args)+2)
	arg[0] = imagePath
	arg[1] = fmt.Sprintf("%s%s%02d%02d%02d%02d%02d%02d%05d", filepath.Dir(imagePath), sep, nt.Year(), nt.Month(), nt.Day(), nt.Hour(), nt.Minute(), nt.Second(), (rand.Intn(10000) + 1000))
	for i, v := range t.Args {
		arg[i+2] = v
	}
	cmd := exec.Command(tesseractPath, arg...)
	cmd.Dir = imagePath[0:strings.LastIndex(imagePath, string(filepath.Separator))]

	err = cmd.Run()
	if err != nil {
		return ocr.Null, err
	}
	resTxt := arg[1] + ".txt"
	data, err := ioutil.ReadFile(resTxt)
	if err != nil {
		return ocr.Null, err
	}
	err = os.Remove(resTxt)
	code := strings.TrimSpace(string(data))
	return code, err
}

func getTesseractPath(dirPath string) (string, error) {
	sep := string(os.PathSeparator)
	path := filepath.Clean(dirPath)
	fs, err := ioutil.ReadDir(path)
	if err != nil {
		return "", err
	}
	for _, v := range fs {
		if v.IsDir() { // 忽略目录
			continue
		}
		if strings.EqualFold(strings.ToLower(v.Name()), "tesseract.exe") {
			return path + sep + v.Name(), nil
		}
	}
	return "", errors.New("don't find the tesseract")
}
